<template>
    <div class="forbid-select">
        <div style="display:flex;justify-content: center;align-items: center;height: 65px;">
            <h2 style="cursor: default;">{{ bucket }}文件列表</h2>
            <el-input v-model="searchKey" size="small" class="search" placeholder="搜索文件">
                <i slot="prefix" class="el-icon-search"
                   style="display: flex;justify-content: center;align-items: center;height: 100%"/>
            </el-input>
        </div>
        <div class="file-container">
            <el-scrollbar style="width: 100%;height: 100%">
                <div v-waterfall>
                    <el-card class="file cursor-default" v-for="(item, index) in showFiles" :key="index">
                        <template #header>
                            <div class="e-page forbid-select card-header">
                                <div class="file-name font-auto-resize cursor-default">
                                    <span>{{ index + 1 }}. {{ item.filename }}</span>
                                </div>
                                <div class="edit-btn cursor-pointer" @click="editFileName(item)">
                                    <el-icon>
                                        <component :is="getIcon('editPen')"/>
                                    </el-icon>
                                </div>
                            </div>
                        </template>
                        <el-row class="bucket-item">
                            <el-col :span="8" class="file-label">文件大小:</el-col>
                            <el-col :span="16" class="file-info">
                                {{ item.hasOwnProperty("size") ? formatSize(item.size) : 0 }}
                                <div class="iconfont icon-tiaozhuan tz cursor-pointer" @click="moveFile(item)"/>
                            </el-col>
                        </el-row>
                        <el-row class="bucket-item">
                            <el-col :span="8" class="file-label">上传时间:</el-col>
                            <el-col :span="16" class="file-info">
                                {{ item.uploadTime }}
                            </el-col>
                        </el-row>
                        <el-row class="bucket-item">
                            <el-col :span="8" class="file-label">文件类型:</el-col>
                            <el-col :span="16" class="file-info">
                                <el-col :span="12">
                                    {{
                                        item.filename && item.filename.lastIndexOf(".") >= 0
                                            ? item.filename.substring(item.filename.lastIndexOf(".") + 1).toLowerCase() :
                                            '其他'
                                    }}
                                </el-col>
                                <el-col :span="12" style="text-align: right">
                                    <!-- <i class="el-icon-copy-document" style="margin-top: 5px;cursor: pointer" @click="share(item)" /> -->
                                    <el-icon style="cursor: pointer" @click="share(item)" class="cursor-pointer">
                                        <component :is="getIcon('CopyDocument')"/>
                                    </el-icon>
                                </el-col>
                            </el-col>
                        </el-row>
                        <el-row class="file-buttons">
                            <el-col :span="isInArray(fileSuffixTypeUtil(item.filename.toLowerCase()), suffix) ? 8 : 12">
                                <el-button class="file-button fit-auto-resize" link @click="download(item)">
                                    下载文件
                                </el-button>
                            </el-col>
                            <el-col :span="8" v-if="fileSuffixTypeUtil(item.filename.toLowerCase()) === 'image'">
                                <el-button class="file-button fit-auto-resize" @click="preview(item)" link>
                                    预览文件
                                </el-button>
                            </el-col>
                            <el-col :span="isInArray(fileSuffixTypeUtil(item.filename.toLowerCase()), suffix) ? 8 : 12">
                                <el-button class="file-button fit-auto-resize" @click="del(item)" link
                                           :confirmTitle="`确定删除文件「${item.filename}」?`">
                                    删除文件
                                </el-button>
                            </el-col>
                        </el-row>
                    </el-card>
                </div>
            </el-scrollbar>
        </div>
        <el-drawer onselectstart="return false;" class="default-cursor" size="50%" ref="drawerRef" :show-close="false"
                   direction="ltr" v-model="shareDrawer" append-to-body @closed="resetShareModel" @open="setShareModel"
                   :with-header="false">
            <el-form inline :model="shareModel" class="e-page form-item form-auto-resize" spellcheck="false"
                     @submit.native.prevent>
                <el-form-item label="文件名" prop="title">
                    <div class="font-auto-resize">{{ shareModel.filename }} < {{ shareModel.bucket }}>
                    </div>
                </el-form-item>
                <el-form-item label="分享策略" prop="executorBlockStrategy">
                    <el-radio-group v-model="shareModel.type">
                        <el-radio value="1">固定时间</el-radio>
                        <el-radio value="2">指定日期</el-radio>
                        <el-radio value="3">永久生效</el-radio>
                    </el-radio-group>
                </el-form-item>
                <el-form-item label="days" prop="title" v-if="shareModel.type === '1'">
                    <el-input-number v-model="shareModel.day" class="input-auto-resize" :max="360" :min="0"/>
                </el-form-item>
                <el-form-item label="hours" prop="title" v-if="shareModel.type === '1'">
                    <el-input-number v-model="shareModel.hour" class="input-auto-resize" :max="24" :min="0"/>
                </el-form-item>
                <el-form-item label="minutes" prop="title" v-if="shareModel.type === '1'">
                    <el-input-number v-model="shareModel.minute" class="input-auto-resize" :max="60" :min="0"/>
                </el-form-item>
                <c_calendar v-if="shareModel.type === '2'" v-model="shareModel.date" :disableDate="disableDate"
                            style="height: 500px;"/>
            </el-form>
            <div class="font-auto-resize link-desc">
                Link will be available until:{{
                    showResult.expire ? showResult.expire.format("YYYY-MM-DD HH:mm:ss") : ""
                }}
            </div>
            <el-input v-model="showResult.url" class="url forbid-select input-auto-resize" disabled>
                <template #suffix>
                    <el-icon @click="copy" style="cursor: pointer;">
                        <component :is="getIcon('copyDocument')" slot="suffix"/>
                    </el-icon>
                </template>
            </el-input>
        </el-drawer>
    </div>
</template>
<script setup>
import {useElMessage, useRequest, useImagePreview, useElMessageBox} from "@usehook"
import {formatSize, isInArray, getIcon, encrypt} from "@/utils/tools"
import {fileSuffixTypeUtil} from "@/utils/fileUtil"
import {baseUrl} from "@/utils/constant"
import {ElInput, ElScrollbar} from "element-plus"
import {withDirectives, resolveDirective} from "vue"

const props = defineProps({
    bucket: {
        type: String,
        required: true
    },
    tags: {
        type: Array,
        default: () => []
    }
})

const download = (item) => {
    let link = document.createElement('a')
    let url = formatDownloadUrl(item)
    url = encodeURI(url).replaceAll(";", encodeURIComponent(encodeURI(';'))).replaceAll("@", encodeURIComponent(encodeURI('@'))).replaceAll("+", encodeURIComponent(encodeURI('+')))
    const filename = item.filename
    fetch(url, {method: 'HEAD'}).then(e => {
        if (e.status === 200) {
            link.href = url
            link.download = filename
            link.click()
        } else {
            useElMessage.error("无权限访问")
        }
    }).catch((e) => {
        console.log(e)
    }).finally(() => {
        link.remove()
    })
}

let file = $ref([])
let currentFile = $ref({url: "", showImage: false, showVideo: false, showTxt: false})
let suffix = ['image']
let searchKey = $ref("")
let shareDrawer = $ref(false)
let shareModel = $ref({
    hour: 0,
    minute: 0,
    day: 1,
    type: "1",
    date: new Date(),
    bucket: "",
    id: "",
    filename: ""
})

let showResult = $ref({
    url: "",
    expire: ""
})

const editFileName = (item) => {
    let filename = $ref(item.filename)
    useElMessageBox("修改文件名称", () => h("div", [h("div", {class: "mdf-content"},
        [h("span", "文件:"), h("span", {
            style: {
                color: "red",
                padding: "0 5px"
            }
        }, item.filename), h("span", "重命名为：")]), h(ElInput, {
        placeholder: "请输入新的文件名称", modelValue: filename, 'onUpdate:modelValue': (val) => {
            filename = val
        }, style: "width:100%;margin-top:10px", class: "filename-input"
    })]), {
        showIcon: false, showCancelButton: true, onOpened: (ele) => {
            ele.querySelector(".filename-input input").focus()
        }
    }).then(() => {
        if (filename && filename !== item.filename) {
            useRequest.post("/file/modifyFilename", {bucket: item.bucket, filename, id: item.id}).then(resp => {
                if (resp && resp.status) {
                    item.filename = filename
                    useElMessage.success("文件名修改成功")
                } else {
                    useElMessage.error("文件名修改失败")
                }
            })
        }
    })
}

const tags = props.tags

const onOpened = (e) => {
    const ele = e.querySelector(".move-file .el-message-box__btns .confirm-button")
    ele.classList.add("is-disabled")
    ele.setAttribute("disabled", "disabled")
}

const waterfall = resolveDirective("waterfall")

const moveFile = (item) => {
    const selected = ref(null)
    const tagItem = tags.filter(e => e.name !== item.bucket).map((current, index) => {
        return h("div", {
            id: "bucket-list-item-" + index,
            class: `bucket-list-item cursor-pointer`, onclick: () => {
                document.querySelectorAll(".bucket-list-item").forEach(e => e.classList.remove("bucket-list-item-active"))
                document.querySelector("#bucket-list-item-" + index).classList.add("bucket-list-item-active")
                selected.value = current
                document.querySelector(".move-file .el-message-box__btns .confirm-button").classList.remove("is-disabled")
                document.querySelector(".move-file .el-message-box__btns .confirm-button").removeAttribute("disabled")
            }
        }, [h("span", {}, (index + 1) + ".桶名称：" + current.name),
            h("div", {style: {paddingLeft: "20px"}}, "占用空间：" + formatSize(current.size)),
            h("div", {style: {paddingLeft: "20px"}}, "已有文件：" + current.files),
            h("div", {style: {paddingLeft: "20px"}}, "创建时间：" + new Date(parseInt(current.creationDate)).format("YYYY-MM-DD HH:mm:ss"))])
    })

    const scrollbar = h(ElScrollbar, {class: "tag-item"}, () => withDirectives(h("div", {}, tagItem), [[waterfall]]))

    const importantStyle = {style: {color: "red", fontSize: "18px"}}
    const moveDesc = () => h("span", [h("span", `文件`), h("span", importantStyle, `${item.filename}`), h("span", `从`), h("span", importantStyle, `${item.bucket}`), h("span", `移动到`), h("span", importantStyle, `${selected.value.name}`)])
    const defaultDesc = () => h("span", [h("span", `准备从`), h("span", importantStyle, `${item.bucket}`), h("span", `移动文件`), h("span", importantStyle, `${item.filename}`)])
    useElMessageBox("移动文件", () => h("div", {}, [h("div", {
            style: {
                height: "35px",
                lineHeight: "35px",
                padding: "0 0 10px 10px"
            }
        }, selected.value ? moveDesc() : defaultDesc()), scrollbar]),
        {showIcon: false, showCancelButton: true, customClass: "move-file", onOpened}).then(() => {
        const data = {bucket: item.bucket, newBucket: selected.value.name, fileId: item.id}
        useRequest.post("/file/moveFile", data).then(resp => {
            if (resp && resp.status) {
                // 将item对象从file列表中移除
                file.splice(file.findIndex(e => e.id === item.id), 1)
            }
        }).catch(err => {
            useElMessage.error(err.message)
        })
    })
}

const showFiles = $computed(() => {
    if (searchKey) {
        if (document.querySelector(".search")) document.querySelector(".search").style.width = '300px'
        return file.filter(e => {
            return e.filename.includes(searchKey) || e.id.includes(searchKey)
        })
    } else {
        if (document.querySelector(".search")) document.querySelector(".search").style.width = '120px'
        return file
    }
})

const resetShareModel = () => {
    shareModel = {
        hour: 0,
        minute: 0,
        day: 1,
        type: "1",
        date: new Date(),
        bucket: "",
        id: "",
        filename: "",
    }
}

const setShareModel = () => {
    shareModel.date = new Date()
}

const copy = () => {
    navigator.clipboard.writeText(showResult.url).then(() => {
        useElMessage.success('文件下载地址复制成功')
    })
}

const share = (item) => {
    shareModel.bucket = item.bucket
    shareModel.id = item.id
    shareModel.filename = item.filename
    shareDrawer = true
}

const formatDownloadUrl = (item) => {
    const sign = encrypt(JSON.stringify({
        name: item.filename,
        id: item.id,
        bucket: item.bucket,
        time: showResult.expire.format('YYYY-MM-DD HH:mm:ss')
    }))
    const url = baseUrl + '/file/get/' + item.bucket + '/' + item.id + '?sign=' + sign
    return encodeURI(url).replaceAll(";", encodeURIComponent(encodeURI(';'))).replaceAll("@", encodeURIComponent(encodeURI('@'))).replaceAll("+", encodeURIComponent(encodeURI('+')))
}

const url = (item) => {
    const url = baseUrl + '/file/get/' + item.bucket + '/' + item.id + '?sign=Smc+w8lCGza5jrp2jpdWb1i1Fsp8lCsA53xtFUZlx'
    return encodeURI(url).replaceAll(";", encodeURIComponent(encodeURI(';'))).replaceAll("@", encodeURIComponent(encodeURI('@'))).replaceAll("+", encodeURIComponent(encodeURI('+')))
}

const preview = (item) => {
    currentFile = {url: url(item) + "&preview&cache", showImage: true}
    //<previewImage :url="currentFile.url" v-model="currentFile.showImage" />
    useImagePreview({url: url(item) + "&preview&cache"})
}

const previewTxt = (item) => {
    currentFile = {url: url(item) + "&preview&cache", showTxt: true}
}

const previewMusic = (item) => {
    const fileInfo = {url: url(item) + "&preview&cache", enable: true, format: fileSuffixTypeUtil(item.filename)}
    // $setEventListener("playMusic", fileInfo)
}

const previewVideo = (item) => {
    currentFile = {url: url(item) + "&preview&cache", showVideo: true}
}

const del = (item) => {
    useRequest({url: "/file/delete", id: item.id, bucket: props.bucket, method: "post"}).then(resp => {
        if (resp.status) {
            if (resp.message) useElMessage(resp.message)
            searchFile()
        }
    })
}

const searchFile = () => {
    useRequest({url: "/file/search", tag: props.bucket}).then(resp => {
        if (resp.status) {
            file = resp.data
        }
    })
}

const disableDate = (day) => {
    const today = new Date()
    today.setHours(0)
    today.setMinutes(0)
    today.setSeconds(0)
    today.setMilliseconds(0)
    return day < today
}

watch(() => shareModel, (value) => {

    if (value.type === "1") {
        const date = new Date()
        date.setHours(date.getHours() + (parseInt(value.hour) || 0))
        date.setDate(date.getDate() + (parseInt(value.day) || 0))
        date.setMinutes(date.getMinutes() + (parseInt(value.minute) || 0))
        showResult.expire = date
    } else if (value.type === '2') {
        showResult.expire = value.date
    } else if (value.type === '3') {
        const date = new Date()
        date.setFullYear(2099, 11, 31)
        date.setHours(8)
        date.setMinutes(0)
        date.setSeconds(0)
        showResult.expire = date
    }

    const sign = encrypt(JSON.stringify({
        name: value.filename,
        id: value.id,
        bucket: value.bucket,
        time: showResult.expire.format('YYYY-MM-DD HH:mm:ss')
    }))
    const url = baseUrl + '/file/get/' + value.bucket + '/' + value.id + '?sign=' + sign
    showResult.url = encodeURI(url).replaceAll(";", encodeURIComponent(encodeURI(';'))).replaceAll("@", encodeURIComponent(encodeURI('@'))).replaceAll("+", encodeURIComponent(encodeURI('+'))) + "&preview&cache"
}, {deep: true, immediate: true})

onMounted(() => {
    searchFile()
})
</script>
<style scoped>
:deep(.file-name) {
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    font-size: var(--font-size);
    cursor: default;
    width: calc(100% - 30px);
    position: relative;
}

:deep(.search) {
    width: 120px;
    margin-top: 5px;
    transition: all .5s ease;
    height: calc(var(--font-size) * 2) !important;
    font-weight: var(--font-weight) !important;
    font-size: var(--font-size) !important;
}

:deep(.search:focus-within) {
    width: 300px !important;
}

:deep(.el-card__header) {
    padding: 10px 15px;
}

:deep(.el-card__body) {
    padding: 10px 15px;
}

:deep(.file-info) {
    height: calc(var(--font-size) * 2);
    line-height: 18px;
    max-width: calc(100% - var(--font-size) * 5);
    display: flex;
    align-items: center;
    position: relative;
}

:deep(.preview .el-dialog__header),
:deep(.preview .el-dialog__body) {
    padding: 0;
}

:deep(.preview .el-dialog.is-fullscreen) {
    overflow: hidden;
}

:deep(.el-image__error) {
    font-size: var(--font-size);
}

:deep(h2) {
    text-align: center;
    margin: 10px;
}

:deep(.file) {
    cursor: default;
}

:deep(.file-button) {
    text-align: center;
    cursor: default;
    color: #8cc5ff;
    padding: 5px;
    background: rgba(213, 213, 213, .2);
    border-radius: 5px;
}

:deep(.file-buttons .file-button:hover) {
    background: rgba(213, 213, 213, .2);
    color: #b5daff;
}

:deep(.file-button.fit-auto-resize) {
    width: 100% !important;
}

:deep(.file-buttons) {
    display: flex;
    align-items: center;
    padding: 10px 0 5px 0;
}

:deep(.file-buttons .el-col) {
    padding-right: 10px;
}

:deep(.file-buttons .el-col:last-child) {
    padding-right: 0;
}

:deep(.el-calendar-table td.is-selected) {
    color: #1989FA;
    background: #f0f0f0 !important;
    position: relative;
}

:deep(.el-calendar-day:hover) {
    background-color: #f0f0f0;
    /* 您可以更改为您想要的颜色 */
}

:deep(.el-calendar-table .el-calendar-day) {
    height: 40px;
    display: flex;
    justify-content: center;
    align-items: center;
}

:deep(.el-input.is-disabled .el-input__inner) {
    cursor: default;
}

:deep(.file-label) {
    justify-content: flex-end;
    padding-right: 10px;
    display: flex;
    align-items: center;
}

:deep(.file-container) {
    width: calc(100% - 10px);
    height: calc(-80px + 100vh);
    padding: 5px;
}

:deep(.edit-btn) {
    position: absolute;
    right: 0px;
    top: 0px;
    height: 100%;
    display: flex;
    justify-content: center;
    align-items: center;
    font-size: var(--font-size);
}

:deep(.tz) {
    position: absolute;
    right: 0;
}
</style>

<style>
.del-dialog .el-message-box__message p {
    overflow: hidden;
    text-overflow: ellipsis;
    font-size: var(--font-size);
}

url .el-input__suffix {
    display: flex;
    right: 11px;
    cursor: pointer;
}

.url .el-input__suffix-inner {
    margin: auto 8px;
}

.url .el-input__inner {
    pointer-events: none;
}

.url {
    position: absolute;
    bottom: 20px;
    text-align: center;
    max-width: calc(100% - 40px);
}

.url .el-input__wrapper {
    cursor: default;
}

.link-desc {
    position: absolute;
    bottom: 80px;
    text-align: center;
    width: calc(100% - 40px);
}

.bucket-list-item {
    line-height: 25px;
    padding: 5px 10px;
    border-radius: 3px;
    background: gainsboro;
    border: 1px solid rgb(105 105 105 / 25%);
}

.bucket-list-item-active {
    background: fixed linear-gradient(to right, #cbcbcb, #52a1d9);
    color: #fff;
}

.bucket-list-item:not(.bucket-list-item-active):hover {
    background: #ebebeb;
}

.move-file {
    top: 10vh;
    min-width: 70%;
}

.move-file .tag-item {
    height: 50vh;
    width: 100%;
}

.move-file .el-scrollbar__bar.is-vertical {
    width: 0 !important;
}
</style>